package net.ming616.nlp.qa.util;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.ming616.nlp.common.model.NLPWord;
import net.ming616.nlp.qa.focus.Focus;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

public class QuestionUtils {
	/**
	 * Logger for this class
	 */
	private static final Logger logger = Logger.getLogger(QuestionUtils.class);

	static Map<String, String> questionWordMap;

	public final static Map<String, String> getQuestionWordMap() {
		if (null == QuestionUtils.questionWordMap) {
			QuestionUtils.questionWordMap = new HashMap<String, String>();
			try {
				List<String> lines = IOUtils.readLines(QuestionUtils.class
						.getResourceAsStream("/interrogative.txt"), "GBK");
				for (String line : lines) {
					String pos = StringUtils.substringBefore(line, "=");
					String text = StringUtils.substringAfter(line, "=");
					String[] words = StringUtils.split(text, ",");
					for (String word : words) {
						QuestionUtils.questionWordMap.put(word, pos);
					}
				}
			} catch (IOException e) {
				logger.error(e.getMessage());
			}
		}
		return QuestionUtils.questionWordMap;
	}

	public final static boolean isQuesitonWord(String word, String pos) {
		if (QuestionUtils.getQuestionWordMap().containsKey(word)) {
			// if (StringUtils.contains(pos, "r")
			// || StringUtils.contains(pos, "m")|| StringUtils.contains(pos,
			// "u")) {
			// return true;
			// }
			return true;
		}
		return false;
	}

	public final static NLPWord getQuestionWord(List<NLPWord> question) {
		NLPWord result = null;
		for (NLPWord nlpWord : question) {
			if (QuestionUtils.getQuestionWordMap().containsKey(
					nlpWord.getText())) {
				result = nlpWord;
			}
		}
		return result;
	}

	public final static List<NLPWord> getQuestionWords(List<NLPWord> question) {
		List<NLPWord> result = new ArrayList<NLPWord>();
		for (NLPWord nlpWord : question) {
			if (QuestionUtils.getQuestionWordMap().containsKey(
					nlpWord.getText())) {
				result.add(nlpWord);
			}
		}
		return result;
	}

	public final static boolean isQuestionWord(NLPWord word) {
		boolean result = false;
		if (QuestionUtils.getQuestionWordMap().containsKey(word.getText())) {
			result = true;
		}
		return result;
	}

	public final static Focus getFocus(List<NLPWord> words) {
		Focus f = new Focus();
		for (NLPWord nlpWord : words) {
			if (isQuestionWord(nlpWord)) {
				f.setFocusText(nlpWord.getText());
				NLPWord parent = getParent(nlpWord, words);
				if (null != parent) {
					if (isCopula(parent)) {
						List<NLPWord> siblings = getSiblings(nlpWord, words);
						StringBuffer target = new StringBuffer();
						for (NLPWord s : siblings) {
							target.append(s.getText());
						}
						f.setTargetText(target.toString());
					} else {
						f.setTargetText(parent.getText());
					}
				}
				break;
			}
		}
		return f;
	}

	public final static NLPWord getParent(NLPWord current, List<NLPWord> words) {
		NLPWord parent = null;
		Integer parentId = current.getParent();
		if (parentId >= 0) {
			parent = words.get(parentId);
		}
		return parent;
	}

	public final static List<NLPWord> getSiblings(NLPWord current,
			List<NLPWord> words) {
		List<NLPWord> siblings = new ArrayList<NLPWord>();
		NLPWord parent = getParent(current, words);
		if (null != parent) {
			for (NLPWord nlpWord : words) {
				if (nlpWord.getParent() == parent.getId()) {
					siblings.add(nlpWord);
				}
			}
		}
		siblings.remove(current);
		return siblings;
	}

	public final static boolean isCopula(NLPWord word) {
		boolean result = false;
		ArrayList<String> copulas = new ArrayList<String>();
		copulas.add("是");
		copulas.add("的");
		copulas.add("为");
		copulas.add("叫");
		copulas.add("指");
		copulas.add("有");
		copulas.add("由");

		if (copulas.contains(word.getText())) {
			result = true;
		}
		return result;

	}
}
